package com.ltxtiyu.video.tool;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import net.sf.jmimemagic.Magic;
import net.sf.jmimemagic.MagicMatch;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;

public class AliTool {
    public static final Logger  LOGGER = LoggerFactory.getLogger(AliTool.class);
    public static final String CONTENT_TYPE_MUSIC = "audio/mp3";    // 上传音乐文件时声明为音乐


	private String endPoind;
	private String accessId;
	private String accessKey;
	private String bucketId;

	public static AliTool getInstance(String endPoind, String accessId,
                                      String accessKey, String bucketId) {
		return new AliTool(endPoind, accessId, accessKey, bucketId);
	}

	public AliTool(String endPoind, String accessId, String accessKey,
                   String bucketId) {
		super();
		this.endPoind = endPoind;
		this.accessId = accessId;
		this.accessKey = accessKey;
		this.bucketId = bucketId;
	}

	public void uploadFileFromFile(String objectId, File file) throws Exception {
		uploadFileFromFile(objectId, file, "image/jpeg");
	}

	public void uploadFileFromFile(String objectId, File file,
                                   String contentType) throws Exception {

		OSSClient client = new OSSClient(endPoind, accessId, accessKey);

		ObjectMetadata objectMeta = new ObjectMetadata();
		objectMeta.setContentLength(file.length());
		objectMeta.setContentType(contentType);

		client.putObject(bucketId, objectId, new FileInputStream(file),
				objectMeta);
	}

	public void uploadFileFromInputStream(String objectId, InputStream ins)
			throws Exception {
		uploadFileFromInputStream(objectId, ins, "image/jpeg");
	}

	public void uploadFileFromInputStream(String objectId, InputStream ins,
                                          String contentType) throws Exception {

		OSSClient client = new OSSClient(endPoind, accessId, accessKey);

		ObjectMetadata objectMeta = new ObjectMetadata();
		objectMeta.setContentLength(ins.available());
		objectMeta.setContentType(contentType);

		client.putObject(bucketId, objectId, ins, objectMeta);
	}

	public void deleteFile(String objectId) throws OSSException,
            ClientException {
		OSSClient client = new OSSClient(endPoind, accessId, accessKey);

		client.deleteObject(bucketId, objectId);
	}

	/**
	 * 
	 * @param objectId
	 * @param expiration millisecond from now date
	 * @return
	 */
	public String getAccessURL(String objectId, long expiration) {
		Date date = new Date();
		date.setTime(date.getTime() + expiration);
		OSSClient client = new OSSClient(endPoind, accessId, accessKey);
		URL url = client.generatePresignedUrl(bucketId, objectId, date);
		return url.toString();
	}

	public void createFolder(String bucketName, String folderName)
			throws IOException {
		OSSClient client = new OSSClient(endPoind, accessId, accessKey);

		ObjectMetadata objectMeta = new ObjectMetadata();
		/*
		 * 这里的size为0,注意OSS本身没有文件夹的概念,这里创建的文件夹本质上是一个size为0的Object,dataStream仍然可以有数据
		 * 照样可以上传下载,只是控制台会对以"/"结尾的Object以文件夹的方式展示,用户可以利用这种方式来实现文件夹模拟功能,创建形式上的文件夹
		 */
		byte[] buffer = new byte[0];
		ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
		objectMeta.setContentLength(0);
		try {
			client.putObject(bucketId, folderName, bais, objectMeta);
		} finally {
			bais.close();
		}
	}

	public String parseAliyunUrl(String objectId){
		if (StringUtils.isNotBlank(objectId)) {
			StringBuffer aliyunUrl = new StringBuffer();
			String[] objectIds = objectId.split(",");
			if (objectIds.length > 0) {
				for (int i = 0; i < objectIds.length; i++) {
					aliyunUrl.append(getAccessURL(objectIds[i]));
					if (i != objectIds.length - 1) {
						aliyunUrl.append(",");
					}
				}
			}
			return aliyunUrl.toString();
		} else {
			return null;
		}
	}

    /**
     * 采用base64传输图片的方式
     * 上传单张图片
     * @param aliTool
     * @param pic
     * @return
     * @throws Exception
     */
    public String updateSinglePic(AliTool aliTool, String pic) {
        // 生成objectId
        String objectId = DigestUtils.md5Hex(UUID.randomUUID().toString());
        try{
            // 上传图片
            @SuppressWarnings("restriction")
            byte[] picByteArray = new BASE64Decoder().decodeBuffer(pic);
            MagicMatch mm = Magic.getMagicMatch(picByteArray);
            aliTool.uploadFileFromInputStream(objectId, new ByteArrayInputStream(picByteArray),
                    mm.getMimeType());
        }catch (Exception e){
            LOGGER.error(">>>>>>>>>>>>>>上传图片发生错误, 错误原因: {}",e);
            objectId = null;
        }finally {
            return objectId;
        }
    }

	public static String getCirclePicObjectId(HttpServletRequest request, AliTool aliTool) throws Exception {
		String objectId = DigestUtils.md5Hex(UUID.randomUUID().toString());
		Uploader up = new Uploader((MultipartHttpServletRequest) request);
		up.setSavePath("/data/temp");
		String[] fileType = { ".gif", ".png", ".jpg", ".jpeg", ".bmp" };
		up.setAllowFiles(fileType);
		up.setMaxSize(10000); // 单位KB
		up.upload();
		String strDirPath = request.getSession().getServletContext().getRealPath("/");


		// 上传临时文件成功 上传阿里云
		if (up.getState().equals("SUCCESS")) {
			// 原图保存到阿里云
			try {
				aliTool.uploadFileFromFile(objectId, new File(strDirPath + up.getUrl()),
						up.getContentType());
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// 删除临时文件
			FileTool.deleteFile(strDirPath + up.getUrl());
			//return WebJsonTool.genJson(WebRetEnum.SUCCESS,"picOid", objectId);
		}
		return objectId;
	}

	public String getEndPoind() {
		return endPoind;
	}

	public void setEndPoind(String endPoind) {
		this.endPoind = endPoind;
	}

	public String getAccessId() {
		return accessId;
	}

	public void setAccessId(String accessId) {
		this.accessId = accessId;
	}

	public String getAccessKey() {
		return accessKey;
	}

	public void setAccessKey(String accessKey) {
		this.accessKey = accessKey;
	}

	public String getBucketId() {
		return bucketId;
	}

	public void setBucketId(String bucketId) {
		this.bucketId = bucketId;
	}


    /**
     * 音乐
     * 上传文件-流
     * @param inputStream
     * @return
     */
    public String uploadFileByStreamForMusic(InputStream inputStream){
        // 生成objectId
        String objectId = DigestUtils.md5Hex(UUID.randomUUID().toString());
        // 设置文件类型, 上传的时候设置好, 查看的时候会用该类型去解析
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(CONTENT_TYPE_MUSIC);       // mp3

        try{
            // 创建OSSClient实例。
            OSSClient ossClient = new OSSClient(endPoind, accessId, accessKey);
            // 上传文件流。
            ossClient.putObject(bucketId, objectId, inputStream,metadata);
            // 关闭OSSClient。
            ossClient.shutdown();
        }catch (Exception e){
            LOGGER.error(">>>>>>>>>>>>>上传music发生错误,objectId:{},错误信息{}",objectId,e);
        }finally {
            return objectId;
        }
    }

    /**
     * 获取文件地址
     * @param objectId
     * @return
     */
    public String getAccessURL(String objectId) {
        Date date = new Date();
        date.setTime(date.getTime() + 1000 * 3600);
        OSSClient client = new OSSClient(endPoind, accessId, accessKey);
        URL url = client.generatePresignedUrl(bucketId, objectId, date);
        return url.toString();
    }



}
